"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lei.chang on '23/04/2023'
    comment: 基础模型定义
"""
from fastapi import Body
from laner.pydantic import BaseModel
from pydantic import Field
from typing import Optional

from project.core.base import UEnum, Element
from project.lib.common import Global
from project.lib.validators import DateTimeStr
from project.lib.validators import generate_validator, MinuteStr


class Operator(BaseModel):
    """ 运营人员信息
    """
    id: int = Field(0, title='运营人员id')
    code: str = Field([], title='运营人员编号')
    name: str = Field([], title='运营人员名称')
    is_admin: bool = Field(False, title='是否管理员')
    is_super_admin: bool = Field(False, title='是否管理员')
    organization_code: str = Field('', title='当前机构编号')
    # func_codes: list[str] = Field([], title='功能权限列表')
    # dev_id: str = Field('', title='设备id')
    token: str = Field('', title='登录者token信息')


class Organization(BaseModel):
    """ 机构相关扩展信息
    """
    code: str = Field('', title='机构编号')
    agent_profile: str = Field('', title='机构编号')
    user_role: str = Field('', title='agent用户角色')
    card_token: str = Field('', title='幻境服务卡片token(冗余)')
    sleep_agent_message: str = Field('', title='睡眠agent话术(冗余)')


class Device(BaseModel):
    """ 设备信息
    """
    organization_code: str = Field('', title='机构编号')
    dev_id: str = Field('', title='设备id')
    code: str = Field('', title='设备id')
    room_no: str = Field('', title='房间号')
    device_type: str = Field('', title='设备类型')
    name: str = Field('', title='设备名称')
    is_forbidden: bool = Field(False, title='是否被禁用')
    room_bind_time: generate_validator(DateTimeStr, none_enable=True) = Field(None, title='绑定房间时间')
    status: str = Field('', title='设备状态', description='online/offline')
    role: str = Field('', title='设备角色', description='user(用户端)/server(服务端)')
    nickname: str = Field('', title='设备昵称')
    organization: Organization = Field(None, title='机构相关扩展信息')
    agent_code: str = Field('', title='设备绑定智能体编号')


class BusinessType(UEnum):
    """ 业务类型
    """
    catering = Element('catering', '餐饮')
    shopping = Element('shopping', '购物')
    other = Element('other', '其它')


class PhoneType(UEnum):
    """ 手机号类型
    """
    eleven_bit = Element('eleven_bit', '11位')
    last_four_bit = Element('last_four_bit', "后4位")


class InvoiceType(UEnum):
    """ 发票类型
    """
    electronic = Element('electronic', '电子发票')
    paper = Element('paper', '纸质发票')


class TitleType(UEnum):
    """ 发票抬头类型
    """
    enterprise = Element('enterprise', '企业单位')
    individual = Element('individual', '个人/非企业单位')


class SelectMode(UEnum):
    """ 选择方式
    """
    single = Element('single', '单选')
    multiple = Element('multiple', '多选')


class MealPeriod(BaseModel):
    """
    """
    start_time: generate_validator(MinuteStr, blank_enable=True) = Body('', title='时段(开始时间)', description='格式: %H:%M')
    end_time: generate_validator(MinuteStr, blank_enable=True) = Body('', title='时段(结束时间)', description='格式: %H:%M')


class Dates(UEnum):
    """ 可选日期
    """
    today = Element('today', '今日')
    tomorrow = Element('tomorrow', '明日')
    after_tomorrow = Element('after_tomorrow', '后日')


class TimeSet(BaseModel):
    """ 时间设置
    """
    dates: list[Dates.enums(fixed=Global.count())] = Body([], title='选择日期', description='today(今日)/tomorrow(明日)/after_tomorrow(后日)')
    meal_period: MealPeriod = Body({}, title='时间段', description='{"start_time": 07:00, "end_time": 08:00}')
    interval: int = Body(0, title='间隔', description='单位: 分钟')
    is_display_reducible: int = Body(0, title='是否展示可约量', description='0: 展示 1: 不展示')


class SopItem(BaseModel):
    """ sop单项格式
    """
    content: str = Field('', max_length=500, title='sop内容')
    node_code: str = Field('', title='节点编号')


class NodeItemDetail(BaseModel):
    """ 节点项目详情
    """
    audio: str = Field('', title='音频文件')
    image: str = Field('', title='图片文件')
    content: str = Field('', title='文本内容')


class Spec(BaseModel):
    """ 项目规格信息
    """
    title: str = Body('', title='规格名称')
    items: list[str] = Body([], title='规格可选列表')


class PageType(UEnum):
    """ 页面类型
    """
    common = Element('common', '普通')
    work_order = Element('work_order', '工单')


class InformEntrance(UEnum):
    """ 通知入口
    """
    NODE = Element('node', '节点中')
    END = Element('process_end', '流程结束')


class InformType(UEnum):
    """ 通知类型
    """
    sms = Element('sms', '短信')
    tel = Element('tel', '电话')


class InformConfig(BaseModel):
    """ 短信配置模版
    """
    flow_role_id: int = Field(0, title='流程角色id')
    flow_process_id: int = Field(0, title='工单状态id')
    inform_type: list[InformType.enums(fixed=Global.count(), with_blank='')] = Body([], title='通知类型 sms(短信)/tel(电话)')


class Item(BaseModel):
    """
    """
    title: str = Field('', title='项目名称')
    image: Optional[str] = Field(None, title='项目图片')
    count: int = Field(None, title='项目数量', description='如果为None, 则不显示数量')
    price: float = Field(None, title='项目单价', description='如果为None, 则不显示单价')
    spec: list[Spec] = Field([], title='选择的规格信息', description='[{"title": xxx, "items": [xxx, xxx, xxx]}, {"title": xxx, "items": [xxx, xxx, xxx]}]')
    date: str = Field('', title='选择的日期', description='today(今日)/tomorrow(明日)/after_tomorrow(后日)/2025-03-14')
    group_title: str = Field('', title='分组名')
    is_spec: bool = Field(False, title='是否选择规格')
    is_count: bool = Field(False, title='是否选择数量')
    count_upper_limit = Field(100, title='数量上限')
    item_type: str = Field('', title='项目类型', description='time_period_str(时间段字符串 xx:xx~xx:xx)/list_image(动态图片列表)/list_text(动态文本列表) 默认: 空')

    time_duration: str = Field('', title='选择的时长')


class Selector(BaseModel):
    """
    """
    node_code: str = Field(..., title='节点编号')
    items: list[Item] = Field([], title='被选择的item')


class TelTemplate(UEnum):
    """ 电话通知模版
    """
    user_sms = Element('xxxx', '服务订单(用户)', role_type='user', content='')
    worker_sms = Element('TTS_313430028', '服务订单(工作人员)', role_type='worker', content='优邸健康提醒您，收到来自${sevice_address}的${sevice_name}订单，请尽快处理。')


class TelTemplateCancel(UEnum):
    """ 短信模版(已取消)
    """
    user_sms = Element('xxxx', '服务订单取消(用户)', role_type='user', content='')
    worker_sms = Element('TTS_313450023', '服务订单取消(工作人员)', role_type='worker', content='优邸健康提醒您，您有一条来自${sevice_address}的${sevice_name}订单已取消，请及时查看。')


class SmsTemplate(UEnum):
    """ 短信模版
    """
    user_sms = Element('SMS_478380735', '服务订单(用户)', role_type='user', content='${sevice_greet}您在${sevice_address}的${sevice_name}订单已生成，已成功预约${sevice_time}的${sevice_details}，详情请点击: notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')
    worker_sms = Element('SMS_478475767', '服务订单(工作人员)', role_type='worker', content='收到一条来自${sevice_address}的${sevice_name}订单，详情请点击: notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')


class SmsTemplateSuccess(UEnum):
    """ 短信模版(已完成)
    """
    user_sms = Element('SMS_478405817', '服务订单完成(用户)', role_type='user', content='您在${sevice_address}的${sevice_name}订单已完成，详情请点击:notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')
    worker_sms = Element('SMS_478620765', '服务订单完成(工作人员)', role_type='worker', content='来自${sevice_address}的${sevice_name}订单已完成，详情请点击: notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')


class SmsTemplateCancel(UEnum):
    """ 短信模版(已取消)
    """
    user_sms = Element('SMS_478575860', '服务订单取消(用户)', role_type='user', content='您在${sevice_address}的${sevice_name}订单已成功取消，详情请点击:notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')
    worker_sms = Element('SMS_478560819', '服务订单取消(工作人员)', role_type='worker', content='来自${sevice_address}的${sevice_name}订单已成功取消，详情请点击: notify.udicaria.com/?record_id=${record_id}&classify_role_id=${classify_role_id}&env=${env}&reserved=${reserved}')


class User(BaseModel):
    """ 用户信息
    """
    bot_id: str = Field('udi', title='数字人id', description='udi/careana/helper 默认udi')
    user_id: str = Field('uu01', title='用户id', description='uu01/nn01 默认uu01')
    dev_id: str = Field('dev01', title='设备id', description='设备id')


class NotifyObject(BaseModel):
    """ 通知对象
    """
    name: str = Field('', title='联系人姓名')
    mobile: str = Field('', title='联系号码')


class Resource(BaseModel):
    """
    """
    resource_paths: list[str] = Field('', title='资源路径')
    description: str = Field('', title='资源描述')


class KnowledgeDataStatus(UEnum):
    """
    """
    init = Element('init', '初始化')
    pdf_converting = Element('pdf_converting', 'pdf转化中')
    md_converting = Element('md_converting', 'md转化中')
    embedding = Element('embedding', '向量化中')
    success = Element('success', '已完成')
    fail = Element('fail', '导入失败')


class RoleType(UEnum):
    """ 角色类型
    """
    user = Element('user', '用户')
    worker = Element('worker', '工作人员')


class ProcessType(UEnum):
    """ 流程状态类型
    """
    cancel = Element(-1, '已取消')


class TimeMode(UEnum):
    """ 时间模式
    """
    period = Element('period', '时间段')
    point = Element('point', '时间点')


class FlushFrequency(UEnum):
    """ 更新频率
    """
    minute = Element('minute', '按分钟')
    hour = Element('hour', '按小时')
    day = Element('day', '按天')
    no_auto = Element('no_auto', '不自动更新')


class SubmitInfo(BaseModel):
    """ 组件提交信息
    """
    flow_page_id: int = Field(..., title='流程页面id')
    submit: str = Field('', title='提交信息')


class FeiShuDocsType(UEnum):
    """ 飞书云文档类型
    """
    base = Element('base', '多维表格')
    sheets = Element('sheets', '电子表格')
    docx = Element('docx', '文档')


class FlushDeviceMode(UEnum):
    """ 设置默认智能体，联动机构设备逻辑
    """
    default_device_only = Element('default_device_only', '只更新旧默认智能体的设备')
    whole_organization = Element('whole_organization', '更新机构下所有设备')
    nothing = Element('nothing', '不做任何事情')
